/**
 * Author: Alec Cove
 * Decompiled by and for the educational purposes of Paul Schoneveld.
 * Paul Schoneveld claims no rights to this code and will not use it in any commercial or personal project.
 * 
 * I (Paul Schoneveld) cannot make the same claims about the math present in this code.  There is no copywrite on 
 * math and I feel that I have full rights to study and recreate the mathematical concepts I see here.
 **/

package 
{
    import flash.display.*;
    import flash.events.*;

    public class Voronoi extends Sprite
    {
        private var rad:Number;
        private var appW:int;
        private var appH:int;
        private var dots:Array;
        private var sy:Array; //Line Start Y
        private var sx:Array; //Line Start X
        private var dpx:Number;
        private var dpy:Number;
        private var storage:int;
        private var theta:Number;
        private var ex:Array; //Line End X
        private var ey:Array; //Line End Y
        private static var PI:Number = 3.14159;
        private static var dotRadius:int = 2;
        private static var PI2:Number = 2 * PI;
        private static var dotColor:int = 16777215;
        private static var lineColor:int = 16777215;

        public function Voronoi()
        {
            stage.frameRate = 500;
            dots = new Array();
            sx = new Array();
            sy = new Array();
            ex = new Array();
            ey = new Array();
            appW = 800--;
            appH = 600--;
            rad = 1;
            theta = 0;
            dpx = appW / 2;
            dpy = appH / 2;
            initDots();
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            addEventListener(Event.ENTER_FRAME, run);
            return;
        }// end function

        private function mouseUpHandler(param1:MouseEvent) : void
        {
            addDot(param1.stageX, param1.stageY);
            return;
        }// end function

        private function drawLine(param1:Number, param2:Number, param3:Number, param4:Number) : void
        {
            graphics.lineStyle(1, lineColor);
            graphics.moveTo(param1, param2);
            graphics.lineTo(param3, param4);
            return;
        }// end function

        private function drawVoronoi() : void
        {
            var i:int;
            var j:int;
            var k:int;
            graphics.clear();
            i = 0;
            while (i < dots.length)
            {
                // Draw each dot
                drawDot(dots[i].x, dots[i].y);
                j = i * storage + i + 1;
                k = i + 1;
                while (k < dots.length + 4)
                {
                    // label
                    if (sx[j] > -Number.MAX_VALUE)
                    {
                        drawLine(sx[j], sy[j], ex[j], ey[j]);
                    }// end if
                    j++;
                    k++;
                }// end while
                i++;
            }// end while
            return;
        }// end function

        private function drawDot(param1:Number, param2:Number) : void
        {
            graphics.lineStyle(0, dotColor);
            graphics.drawCircle(param1, param2, dotRadius);
            return;
        }// end function

        private function autoA() : void
        {
            rad += 1.5;
            theta += 0.4;
            dpx += Math.cos(theta) * rad;
            dpy += Math.sin(theta) * rad;
            addDot(dpx, dpy);
            if (dots.length > 200)
            {
                removeEventListener(Event.ENTER_FRAME, run);
            }// end if
            return;
        }// end function

        private function setVoronoi() : void
        {
            var i:int;
            var k:int;
            var _loc_3:int;
            var _loc_4:int;
            var j:int;
            var m:Number; //Slope
            var Y_intercept:Number;
            var m1:Number; //Another Slope
            var y1:Number;
            var _loc_10:Number;
            var _loc_11:Number;
            var _loc_12:Number;
            var _loc_13:Number;
            var dot1X:Number;
            var dot1Y:Number;
            var dot2X:Number;
            var dot2Y:Number;
            i = 0;
            while (i < dots.length)
            {
                // label
                dot1X = dots[i].x;
                dot1Y = dots[i].y;
                j = i * storage + i + 1;
                k = i + 1;
                while (k < dots.length)
                {
                    // label
                    dot2X = dots[k].x;
                    dot2Y = dots[k].y;
                    if (dot2X == dot1X)
                    {
                        m = 0;
                    }
                    else if (dot2Y == dot1Y)
                    {
                        m = 10000;
                    }
                    else
                    {
                        m = -1 / ((dot2Y - dot1Y) / (dot2X - dot1X));
                    }// end else if
                    Y_intercept = (dot1Y + dot2Y) / 2 - m * (dot1X + dot2X) / 2;
                    if (m > -1 && m <= 1)
                    {
                        sx[j] = 0;
                        sy[j] = m * sx[j] + Y_intercept;
                        ex[j] = appW--;
                        ey[j] = m * ex[j] + Y_intercept;
                    }
                    else
                    {
                        sy[j] = 0;
                        sx[j] = (sy[j] - Y_intercept) / m;
                        ey[j] = appH--;
                        ex[j] = (ey[j] - Y_intercept) / m;
                    }// end else if
                    j++;
                    k++;
                }// end while
                sx[j] = 0;
                sy[j] = 0;
                ex[j] = appW;
                ey[j] = 0;
                j++;
                sx[j] = 0.1;
                sy[j] = 0;
                ex[j] = 0;
                ey[j] = appH;
                j++;
                sx[j] = appW;
                sy[j] = 0;
                ex[j] = appW - 0.1;
                ey[j] = appH;
                j++;
                sx[j] = 0;
                sy[j] = appH;
                ex[j] = appW;
                ey[j] = appH;
                i++;
            }// end while
            i = 0;
            while (i < dots.length)
            {
                // label
                dot1X = dots[i].x;
                dot1Y = dots[i].y;
                k = 0;
                while (k < dots.length + 4)
                {
                    // label
                    if (k != i)
                    {
                        if (k > i)
                        {
                            j = i * storage + k;
                        }
                        else
                        {
                            j = k * storage + i;
                        }// end else if
                        if (sx[j] > -Number.MAX_VALUE)
                        {
                            m1 = (ey[j] - sy[j]) / (ex[j] - sx[j]);
                            y1 = sy[j] - m1 * sx[j];
                            _loc_3 = i + 1;
                            while (_loc_3 < dots.length + 4)
                            {
                                // label
                                if (_loc_3 != k)
                                {
                                    _loc_4 = i * storage + _loc_3;
                                    if (sx[_loc_4] > -Number.MAX_VALUE)
                                    {
                                        _loc_10 = (ey[_loc_4] - sy[_loc_4]) / (ex[_loc_4] - sx[_loc_4]);
                                        _loc_11 = sy[_loc_4] - _loc_10 * sx[_loc_4];
                                        _loc_12 = (-(_loc_11 - y1)) / (_loc_10 - m1);
                                        _loc_13 = m1 * _loc_12 + y1;
                                        if ((m1 * dot1X + y1 - dot1Y) * (m1 * sx[_loc_4] + y1 - sy[_loc_4]) < 0)
                                        {
                                            sx[_loc_4] = _loc_12;
                                            sy[_loc_4] = _loc_13;
                                        }// end if
                                        if ((m1 * dot1X + y1 - dot1Y) * (m1 * ex[_loc_4] + y1 - ey[_loc_4]) < 0)
                                        {
                                            if (sx[_loc_4] == _loc_12)
                                            {
                                                sx[_loc_4] = -Number.MAX_VALUE;
                                            }
                                            else
                                            {
                                                ex[_loc_4] = _loc_12;
                                                ey[_loc_4] = _loc_13;
                                            }// end if
                                        }// end if
                                    }// end if
                                }// end else if
                                _loc_3++;
                            }// end while
                        }// end if
                    }// end if
                    k++;
                }// end while
                i++;
            }// end while
            return;
        }// end function

        private function run(e:Event) : void
        {
            setVoronoi();
            drawVoronoi();
            return;
        }// end function

        private function initDots() : void
        {
            return;
        }// end function

        private function addDot(_x:int, _y:int) : void
        {
            var dot:Object;
            dot = new Object();
            dot.x = _x;
            dot.y = _y;
            dots.push(dot);
            storage = dots.length + 4;
            return;
        }// end function

    }
}
